home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / cross / avra-0.4_src.lha / avra-0.4 / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-24  |  6.2 KB  |  243 lines

  1. /***********************************************************************
  2.  *  avra - Assembler for the Atmel AVR microcontroller series
  3.  *  Copyright (C) 1998-1999 Jon Anders Haugum
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  18.  *  Boston, MA 02111-1307, USA.
  19.  *
  20.  *
  21.  *  Author of avra can be reached at:
  22.  *     email: jonah@omegav.ntnu.no
  23.  *     www: http://www.omegav.ntnu.no/~jonah/el/avra.html
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <time.h>
  30.  
  31. #include "misc.h"
  32. #include "avra.h"
  33.  
  34.  
  35. int open_out_files(struct prog_info *pi, char *filename)
  36.     {
  37.     int length;
  38.     char *buff;
  39.     time_t tp;
  40.  
  41.     length = strlen(filename);
  42.     buff = malloc(length + 9);
  43.     if(buff)
  44.         {
  45.         strcpy(buff, filename);
  46.         if(length >= 4)
  47.             if(!nocase_strcmp(&buff[length - 4], ".asm"))
  48.                 {
  49.                 length -= 4;
  50.                 buff[length] = '\0';
  51.                 }
  52.         strcpy(&buff[length], ".list");
  53.         pi->list_file = fopen(buff, "w");
  54.         if(pi->cseg_count)
  55.             {
  56.             strcpy(&buff[length], ".hex");
  57.             pi->hfi = open_hex_file(buff);
  58.             strcpy(&buff[length], ".obj");
  59.             pi->obj_file = open_obj_file(pi, buff);
  60.             }
  61.         if(pi->eseg_count)
  62.             {
  63.             strcpy(&buff[length], ".eep.hex");
  64.             pi->eep_hfi = open_hex_file(buff);
  65.             }
  66.         free(buff);
  67.         if(pi->list_file && pi->obj_file && (!pi->cseg_count || pi->hfi) && (!pi->eseg_count || pi->eep_hfi))
  68.             {
  69.             if(time(&tp) != -1)
  70.                 fprintf(pi->list_file, "\navra   ver. %d.%d  %s %s\n\n", VERSION, REVISION, filename, ctime(&tp));
  71.             return(True);
  72.             }
  73.         else
  74.             close_out_files(pi);
  75.         }
  76.     else
  77.         print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  78.     return(False);
  79.     }
  80.  
  81.  
  82. void close_out_files(struct prog_info *pi)
  83.     {
  84.     if(pi->hfi) close_hex_file(pi->hfi);
  85.     if(pi->eep_hfi) close_hex_file(pi->eep_hfi);
  86.     if(pi->list_file)
  87.         {
  88.         if(pi->error_count == 0)
  89.             fprintf(pi->list_file, "\nAssembly complete with no errors.\n");
  90.         fclose(pi->list_file);
  91.         }
  92.     if(pi->obj_file) close_obj_file(pi, pi->obj_file);
  93.     }
  94.  
  95.  
  96. struct hex_file_info *open_hex_file(char *filename)
  97.     {
  98.     struct hex_file_info *hfi;
  99.  
  100.     hfi = calloc(1, sizeof(struct hex_file_info));
  101.     if(hfi)
  102.         {
  103.         hfi->fp = fopen(filename, "wb");
  104.         if(!hfi->fp)
  105.             {
  106.             close_hex_file(hfi);
  107.             hfi = NULL;
  108.             }
  109.         }
  110.     return(hfi);
  111.     }
  112.  
  113.  
  114. void close_hex_file(struct hex_file_info *hfi)
  115.     {
  116.     int i;
  117.     unsigned char checksum = 0;
  118.  
  119.     if(hfi->fp)
  120.         {
  121.         if(hfi->count != 0)
  122.             {
  123.             fprintf(hfi->fp, ":%02X%04X00", hfi->count, hfi->linestart_addr);
  124.             checksum -= hfi->count + ((hfi->linestart_addr >> 8) & 0xff) + (hfi->linestart_addr & 0xff);
  125.             for(i = 0; i < hfi->count; i++)
  126.                 {
  127.                 fprintf(hfi->fp, "%02X", hfi->hex_line[i]);
  128.                 checksum -= hfi->hex_line[i];
  129.                 }
  130.             fprintf(hfi->fp, "%02X\x0d\x0a", checksum);
  131.             }
  132.         fprintf(hfi->fp, ":00000001FF\x0d\x0a");
  133.         fclose(hfi->fp);
  134.         }
  135.     free(hfi);
  136.     }
  137.  
  138.  
  139. void write_ee_byte(struct prog_info *pi, int address, unsigned char data)
  140.     {
  141.     if((pi->eep_hfi->count == 16) || ((address != (pi->eep_hfi->linestart_addr + pi->eep_hfi->count)) && (pi->eep_hfi->count != 0)))
  142.         do_hex_line(pi->eep_hfi);
  143.     if(pi->eep_hfi->count == 0)
  144.         pi->eep_hfi->linestart_addr = address;
  145.     pi->eep_hfi->hex_line[pi->eep_hfi->count++] = data;
  146.     }
  147.  
  148.  
  149. void write_prog_word(struct prog_info *pi, int address, int data)
  150.     {
  151.     write_obj_record(pi, address, data);
  152.     address *= 2;
  153.     if((pi->hfi->count == 16) || ((address != (pi->hfi->linestart_addr + pi->hfi->count)) && (pi->hfi->count != 0)))
  154.         do_hex_line(pi->hfi);
  155.     if(pi->hfi->count == 0)
  156.         pi->hfi->linestart_addr = address;
  157.     pi->hfi->hex_line[pi->hfi->count++] = data & 0xff;
  158.     pi->hfi->hex_line[pi->hfi->count++] = (data >> 8) & 0xff;
  159.     }
  160.  
  161.  
  162. void do_hex_line(struct hex_file_info *hfi)
  163.     {
  164.     int i;
  165.     unsigned char checksum = 0;
  166.  
  167.     fprintf(hfi->fp, ":%02X%04X00", hfi->count, hfi->linestart_addr);
  168.     checksum -= hfi->count + ((hfi->linestart_addr >> 8) & 0xff) + (hfi->linestart_addr & 0xff);
  169.     for(i = 0; i < hfi->count; i++)
  170.         {
  171.         fprintf(hfi->fp, "%02X", hfi->hex_line[i]);
  172.         checksum -= hfi->hex_line[i];
  173.         }
  174.     fprintf(hfi->fp, "%02X\x0d\x0a", checksum);
  175.     hfi->count = 0;
  176.     }
  177.  
  178.  
  179. FILE *open_obj_file(struct prog_info *pi, char *filename)
  180.     {
  181.     int i;
  182.     FILE *fp;
  183.     struct include_file *include_file;
  184.  
  185.     fp = fopen(filename, "wb");
  186.     if(fp)
  187.         {
  188.         i = pi->cseg_count * 9 + 26;
  189.         fputc((i >> 24) & 0xff, fp);
  190.         fputc((i >> 16) & 0xff, fp);
  191.         fputc((i >> 8) & 0xff, fp);
  192.         fputc(i & 0xff, fp);
  193.         i = 26;
  194.         fputc((i >> 24) & 0xff, fp);
  195.         fputc((i >> 16) & 0xff, fp);
  196.         fputc((i >> 8) & 0xff, fp);
  197.         fputc(i & 0xff, fp);
  198.         fputc(9, fp);
  199.         i = 0;
  200.         for(include_file = pi->first_include_file; include_file; include_file = include_file->next)
  201.             i++;
  202.         fputc(i, fp);
  203.         fprintf(fp, "AVR Object File");
  204.         fputc('\0', fp);
  205.         }
  206.     return(fp);
  207.     }
  208.  
  209.  
  210. void close_obj_file(struct prog_info *pi, FILE *fp)
  211.     {
  212.     struct include_file *include_file;
  213.  
  214.     for(include_file = pi->first_include_file; include_file; include_file = include_file->next)
  215.         {
  216.         fprintf(fp, "%s", include_file->name);
  217.         fputc('\0', fp);
  218.         }
  219.     fputc('\0', fp);
  220.     fclose(fp);
  221.     }
  222.  
  223.  
  224. void write_obj_record(struct prog_info *pi, int address, int data)
  225.     {
  226.     fputc((address >> 16) & 0xff, pi->obj_file);
  227.     fputc((address >> 8) & 0xff, pi->obj_file);
  228.     fputc(address & 0xff, pi->obj_file);
  229.     fputc((data >> 8) & 0xff, pi->obj_file);
  230.     fputc(data & 0xff, pi->obj_file);
  231.     fputc(pi->fi->include_file->num & 0xff, pi->obj_file);
  232.     fputc((pi->fi->line_number >> 8) & 0xff, pi->obj_file);
  233.     fputc(pi->fi->line_number & 0xff, pi->obj_file);
  234.     if(pi->macro_call)
  235.         fputc(1, pi->obj_file);
  236.     else
  237.         fputc(0, pi->obj_file);
  238.     }
  239.  
  240.  
  241.  
  242.  
  243.  
  244.